package com.atguigu.meinian.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.atguigu.meinian.constant.MessageConstant;
import com.atguigu.meinian.mapper.MemberMapper;
import com.atguigu.meinian.mapper.OrderMapper;
import com.atguigu.meinian.mapper.OrdersettingMapper;
import com.atguigu.meinian.mapper.SetmealMapper;
import com.atguigu.meinian.pojo.Member;
import com.atguigu.meinian.pojo.Order;
import com.atguigu.meinian.pojo.OrderSetting;
import com.atguigu.meinian.pojo.Setmeal;
import com.atguigu.meinian.service.OrderSerivce;
import com.atguigu.meinian.service.SetmealService;
import com.atguigu.meinian.vo.OrderVo;
import com.atguigu.meinian.vo.R;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zbystart
 * @create 2021-06-24 10:15
 */
@Service(interfaceClass = OrderSerivce.class)
@Transactional
public class OrderSerivceImpl implements OrderSerivce {

    @Autowired
    private OrdersettingMapper ordersettingMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private SetmealMapper setmealMapper;


    /**
     * 保存订单信息
     * @param map
     * @return
     */
    @Override
    public R saveOrder(Map<String, String> map) throws Exception {

        // 1.取出预约信息，判断预约的日期是否有开团计划
        String orderDate = map.get("orderDate");
        Date date = new SimpleDateFormat("yyyy-MM-dd").parse(orderDate);
        Integer orderId = null;
        OrderSetting orderSetting = ordersettingMapper.selectOrdersettingCount(date);

        if (orderSetting != null) {
            // 有：
            // 在判断预约日期预约的人数是否充足
            if (orderSetting.getNumber() - orderSetting.getReservations() > 0) {
                // 充足
                // 根据手机号查询当前预约人是否是会员
                String telephone = map.get("telephone");
                Member member = memberMapper.selectMemberInfoByPhone(telephone);
                String setmealId = map.get("setmealId");
                if (member != null) {
                    // 判断此会员是否已经预约过此套餐（一个会员、一个时间、一个套餐不能重复，否则是重复预约）
                    int count = orderMapper.selectOrderByPhoneAndDateAndSetmeal(member.getId(),date,setmealId);
                    if (count > 0) {
                        // 此会员已经在当前预约日期预约了这个套餐
                        return R.error(MessageConstant.HAS_ORDERED);
                    }
                    // 没有预约过就保存
                } else {
                    // 不是会员，就新建一个会员，并保存订单信息
                    member = new Member();
                    member.setName(map.get("name"));
                    member.setIdCard(map.get("idCard"));
                    member.setRegTime(new Date());
                    member.setSex(map.get("sex"));
                    member.setPhoneNumber(telephone);
                    // 保存会员
                    memberMapper.insertMember(member);
                }
                // 封装订单信息
                Order order = new Order(member.getId(),date,Order.ORDERTYPE_WEIXIN,Order.ORDERSTATUS_NO,Integer.valueOf(setmealId));
                orderMapper.insertOrder(order);
                orderId = order.getId();
                // 当前预约的日期可预约的人数-1，已预约人数+1
                int i = ordersettingMapper.updateNUmberAndReservationsByDate(date);
                if (i <= 0) {
                    // 避免在并发访问，多个用户在同一个日期进行预约，并且这个日期可预约人数只有一个时，出现预约人数出现负数的问题
                    // 修改预约失败了，说明可预约人数不足
                    throw new RuntimeException(MessageConstant.ORDER_FULL);
                }
            } else {
                // 不充足：返回
                return R.error(MessageConstant.ORDER_FULL);
            }
        } else {
            // 没有：返回当前预约的日期没有开团
            return R.error(MessageConstant.SELECTED_DATE_CANNOT_ORDER);
        }

        // 预约成功
        return R.ok(MessageConstant.ORDER_SUCCESS,orderId);
    }

    @Override
    public Map<String, Object> queryOrderInfoByOrderId(Integer id) {
        // 查询订单信息
        Map<String, Object> map = orderMapper.selectOrderInfoAndMemberInfoAndSetmealInfoByOrderId(id);
        // 格式化时间
        String orderDate = new SimpleDateFormat("yyyy-MM-dd").format(map.get("orderDate"));
        map.put("orderDate",orderDate);
        return map;
    }

    @Override
    public Map<String, Object> selectHotSetmealOrderCount(int i) {


        List<Map<String,Object>> countMap = orderMapper.selectHotSetmealOrderCount(i);
        List<String> setmealNames = new ArrayList<>();

        countMap = countMap.stream().map(item -> {

            Setmeal setmeal = setmealMapper.selectSetmealById((Integer) item.get("name"));
            String setmealName = setmeal.getName();
            setmealNames.add(setmealName);
            item.put("name", setmealName);
            return item;
        }).collect(Collectors.toList());

        HashMap<String, Object> map = new HashMap<>();
        map.put("setmealNames",setmealNames);
        map.put("setmealCount",countMap);
        return map;
    }
}
